﻿/*
 * DbFileExplorer
 *
 * Copyright (c) 2012, Stephane Cuillerdier
 * All rights reserved.
 * 
 * This software is licensed under the new BSD License:
 * 
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, 
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice, 
 * this list of conditions and the following disclaimer in the documentation 
 * and/or other materials provided with the distribution.
 * 
 * Neither the name of the author nor the names of its contributors may 
 * be used to endorse or promote products derived from this software without 
 * specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
 * POSSIBILITY OF SUCH DAMAGE.
 * 
 * version 1.0
 */
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

namespace DBFileExplorer
{
	/// <summary>
	/// Description of CritereTriControl.
	/// </summary>
	public partial class CritereTriControl : UserControl
	{
		public bool ModeFusion;
		private MainForm ptrMainForm;
		
		public CritereTriControl()
		{
			//
			// The InitializeComponent() call is required for Windows Forms designer support.
			//
			InitializeComponent();
			
			listCriteresTri.AllowDrop = true;
            treeCriteres.AllowDrop = true;
            
            ModeFusion = false;
		}
		
		public int SetMainFormPointer(MainForm mf)
		{
			// Pointeur sur la MainForm
			if ( mf != null ) 
			{
				ptrMainForm = mf;
				return 0;
			}
			return 1;
			
		}
		
		~CritereTriControl() // On va sauvegarder la config
		{
		
		}
		
		void ListCriteresTriDragLeave(object sender, EventArgs e)
		{
			
		}
		
		void TreeCriteresDragOver(object sender, DragEventArgs e)
		{
			
		}
		
		void TreeCriteresDragEnter(object sender, DragEventArgs e)
		{
			// this code can be in DragOver also
            if (e.Data.GetDataPresent(typeof(ListViewItem)))
                e.Effect = DragDropEffects.Move;
		}
		
		// Deposer un item de la critere list sur la tree view 
		void TreeCriteresDragDrop(object sender, DragEventArgs e)
		{
			if (e.Data.GetDataPresent(typeof(ListViewItem)))
            {
				char champAssocChr = ptrMainForm.OptionsParam.Associateur_de_champ;
				string champAssocStr = champAssocChr.ToString();
				
				ListViewItem li = (ListViewItem)e.Data.GetData(typeof(ListViewItem));

                bool dupplicate = false;

                foreach (TreeNode tn in treeCriteres.Nodes)
                {
                    if (tn.Text == li.Text) dupplicate = true;
                }

                if (!dupplicate)
                {
                	// on verfie s'il y a un node desous la souris
                	Point pt = new Point(e.X, e.Y);
					pt = treeCriteres.PointToClient(pt);
                	TreeNode tNode = treeCriteres.GetNodeAt(pt);
                	// bien faire attention que le tag suive bien car c'est lui contient la positionde l'item dans la liste de base
                	if (tNode != null ) 
                	{
                		if ( ModeFusion == false )
                		{
	                		// verifier s'il a deja des enfants
	                		// si c'est le cas alors on intercale l'item
	                		if ( tNode.Nodes.Count > 0 )
	                		{
	                			TreeNode nodeChild = tNode.Nodes[0];
	                			nodeChild.Remove();
	                			TreeNode nodeJustInserted = tNode.Nodes.Insert(0, li.Text, li.Text);
	                			nodeJustInserted.Tag = li.Tag;
	                			nodeJustInserted.Nodes.Insert(0, nodeChild);
	                		}
	                		else
	                		{
	                			tNode.Nodes.Add(li.Text, li.Text).Tag = li.Tag; // on fait en sorte d'y mettre un Searchkey = au nom du noeud
	                		}
                		}
                		else
                		{
                			// ModeFusion signfie que je vais pouvoir fusionner deux champs en un seul.
                			// dans ce contexte seul la desi et le tag change pas les noeuds enfants
                			string nodeText = tNode.Text + champAssocStr + li.Text;
                			tNode.Text = nodeText;
                			string nodeTag = Convert.ToString(tNode.Tag) + champAssocStr + Convert.ToString(li.Tag);
                			tNode.Tag = nodeTag;
                		}
                		listCriteresTri.Items.Remove(li);
                	}
                	else
                	{
                		if ( treeCriteres.Nodes.Count == 0 ) 
                		{
                			treeCriteres.Nodes.Add(li.Text, li.Text).Tag = li.Tag; // on fait en sorte d'y mettre un Searchkey = au nom du noeud
                			listCriteresTri.Items.Remove(li);
                		}
                	}
                    
                }
            }
			treeCriteres.ExpandAll();
		}
		
		void ListCriteresTriItemDrag(object sender, ItemDragEventArgs e)
		{
			 listCriteresTri.DoDragDrop(e.Item, DragDropEffects.Move);
		}
		
		void TreeCriteresItemDrag(object sender, ItemDragEventArgs e)
		{
			treeCriteres.DoDragDrop(e.Item, DragDropEffects.Move);
		}
		
		void ListCriteresTriMouseDown(object sender, MouseEventArgs e)
		{
			
		}
		
		void ListCriteresTriDragEnter(object sender, DragEventArgs e)
		{
			// this code can be in DragOver also
            if (e.Data.GetDataPresent(typeof(TreeNode)))
                e.Effect = DragDropEffects.Move;
		}
		
		// Deposer un item de la tree view sur la critere list
		void ListCriteresTriDragDrop(object sender, DragEventArgs e)
		{
			if (e.Data.GetDataPresent(typeof(TreeNode)))
            {
                char champAssocChr = ptrMainForm.OptionsParam.Associateur_de_champ;
				string champAssocStr = champAssocChr.ToString();
				
				TreeNode node = (TreeNode) e.Data.GetData(typeof(TreeNode));
                TreeNode nodeTmp = null;
	            while ( node != null )
                {       
	            	string tagStr = Convert.ToString(node.Tag);
                	if ( tagStr.Contains(champAssocStr) ) // ModeFusion
                	{
                		// il s'agit de separer chaque item séparé par le +
                		string[] tabTag = tagStr.Split(champAssocChr);
                		string[] tabName = node.Text.Split(champAssocChr);
                		int idx = 0;
                		foreach( string str in tabName ) // on considere que tag et name ont autant de plus l'un que l'autre
                		{
                			int pos = Convert.ToInt32(tabTag[idx]);
                			listCriteresTri.Items.Insert(pos, str, str, node.ImageIndex).Tag = pos; // on fait en sorte d'y mettre un Searchkey = au nom de l'item
	                		idx++;
                		}
                	}
                	else
                	{
                		int pos = Convert.ToInt32(node.Tag);
	                	listCriteresTri.Items.Insert(pos, node.Text, node.Text, node.ImageIndex).Tag = node.Tag; // on fait en sorte d'y mettre un Searchkey = au nom de l'item
                	}
                	if ( node.Nodes.Count > 0 ) nodeTmp = node.Nodes[0];
                	else nodeTmp = null;
	                node.Remove();
	                node = nodeTmp;
                }
            }
		}
	}
}
